package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.item.config.ThreadPoolConfig;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.model.product.BaseCategoryView;
import com.atguigu.gmall.model.product.SkuInfo;
import com.atguigu.gmall.model.product.SpuSaleAttr;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 商品详情页面 数据汇总
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;//放进spring容器，不会随着方法的销毁而销毁
    @Autowired
    private ListFeignClient listFeignClient;

    //查询商品详情页面所有数据
    //多线程的数据共享在堆里面
    @Override
    public Map getItem(Long skuId) {
        Map result = new HashMap();//map在主线程里面
        //采用异步编排
        //1.库存数据
        CompletableFuture<SkuInfo> skuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
            result.put("skuInfo", skuInfo);
            return skuInfo;
        }, threadPoolExecutor);
        //2:根据category3_id 三级分类的Id查询二级分类的ID及名称、一级分类的ID及名称
        CompletableFuture<Void> categoryViewCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {
            /**thenAcceptAsync无法将自己的返回值给下一个线程使用
             * whenCompleteAsync 可以做到
             */

            BaseCategoryView baseCategoryView = productFeignClient.getBaseCategoryView(skuInfo.getCategory3Id());
            result.put("categoryView", baseCategoryView);
        }, threadPoolExecutor);
        //3:单独查询价格
        CompletableFuture<Void> priceCompletableFuture = CompletableFuture.runAsync(() -> {

            BigDecimal price = productFeignClient.getPrice(skuId);
            result.put("price", price);
        }, threadPoolExecutor);

        //4:
        // -- 根据商品ID查询销售属性及销售属性值集合
        // -- 并且根据当前skuId库存ID查询出对应的销售属性值
        CompletableFuture<Void> spuSaleAttrListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {

            List<SpuSaleAttr> spuSaleAttrListCheckBySku = productFeignClient.
                    getSpuSaleAttrListCheckBySku(skuInfo.getId(), skuInfo.getSpuId());
            result.put("spuSaleAttrList", spuSaleAttrListCheckBySku);
        }, threadPoolExecutor);

        //5.查询组合对应库存ID
        //“属性值1|属性值2|属性值3：skuId”的一个json串以提供页面进行匹配
        CompletableFuture<Void> valuesSkuJsonCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync((skuInfo) -> {

            Map map = productFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
            result.put("valuesSkuJson", JSON.toJSONString(map));//把map转换成json格式字符串
        }, threadPoolExecutor);

        //6.增加当前库存热度   .不需要主服务等
        CompletableFuture.runAsync(() -> {
            listFeignClient.incrHotScore(skuId);
        }, threadPoolExecutor);


        CompletableFuture.allOf(skuInfoCompletableFuture,
                categoryViewCompletableFuture,
                priceCompletableFuture,
                spuSaleAttrListCompletableFuture,
                valuesSkuJsonCompletableFuture).join();
        return result;


        /*//不采用异步编排
        //1.库存数据
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
        result.put("skuInfo",skuInfo);
        //2:根据category3_id 三级分类的Id查询二级分类的ID及名称、一级分类的ID及名称
        BaseCategoryView baseCategoryView = productFeignClient.getBaseCategoryView(skuInfo.getCategory3Id());
        result.put("categoryView",baseCategoryView);

        //3:单独查询价格
        BigDecimal price = productFeignClient.getPrice(skuId);
        result.put("price",price);

        //4:
        // -- 根据商品ID查询销售属性及销售属性值集合
        // -- 并且根据当前skuId库存ID查询出对应的销售属性值
        List<SpuSaleAttr> spuSaleAttrListCheckBySku = productFeignClient.
                getSpuSaleAttrListCheckBySku(skuInfo.getId(), skuInfo.getSpuId());
        result.put("spuSaleAttrList", spuSaleAttrListCheckBySku);

        //5.查询组合对应库存ID
        //“属性值1|属性值2|属性值3：skuId”的一个json串以提供页面进行匹配
        Map map = productFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
        result.put("valuesSkuJson", JSON.toJSONString(map));//把map转换成json格式字符串
        return result;*/
    }
}
